#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

using namespace std;

#define TNUM 4
typedef void (*func_t)(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond);
// typedef void (*func_t)(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond);
volatile bool quit = false;

// 这里需要对线程进行封装
class ThreadData
{
public:
    ThreadData(const string &name, func_t func, pthread_mutex_t *mutex, pthread_cond_t *cond)
        : _name(name), _func(func), _mutex(mutex), _cond(cond)
    {
    }

public:
    string _name;
    func_t _func;
    pthread_mutex_t *_mutex;
    pthread_cond_t *_cond;
};
void func1(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    pthread_mutex_lock(mutex);
    pthread_cond_wait(cond);
    cout << "running -- 下载" << endl;
    pthreda_mutex_unlock(mutex);
}
void func2(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond);
        if (!quit)
        {
            cout << "running -- 打印" << endl;
        }
        pthread_mutex_unlock(mutex);
    }
}
void func3(const string &name, pthred_mutext_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond);
        cout << "running -- 扫描用户信息" << endl;
        pthread_mutex_unlock(mutex);
    }
}
void func4(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond);
        cout << "running -- 读取用户信息" << endl;
        pthread_mutex_unlock(mutex);
    }
}
int main()
{
    pthread_mutex_t mutex;
    pthread_cond_t cond;

    pthread_mutex_init(muetx);
    pthread_cond_init(cond);
    pthread_t tid[TNUM];

    func_t funcs[TNUM] = {func1, func2, func3, func4};
    for (int i = 0; i < TNUM; i++)
    {
        string name = "thread";
        name += to_string(i + 1);
        ThreadData *td = new ThreadData(name, funcs, mutex, cond);
        pthread_create(tid + i, nullptr, Entry, (void *)td);
    }
    sleep(5);
    int cnt = 5;
    while (cnt--)
    {
        pthread_cond_signal(cond);
        cout << "thread wait" << cnt-- << endl;
        sleep(1);
    }
    quit=true;
    for(int i=0;i<TNUM;i++)
    {
        pthread_join(tid[i],nullptr);
        cout<<"thread"<<tid[i]<<endl;
    }
    pthread_mutex_destroy(mutex);
    pthread_cond_destroy(cond);
    return 0;
}
class ThreadData
{
public:
    ThreadData(const string &name, func_t func, pthread_mutex_t *mutex, pthread_cond_t *cond)
        : _name(name), _func(func), _mutex(mutex), _cond(cond)
    {
    }

public:
    string _name;
    pthread_mutex_t *_mutex;
    pthread_cond_t *_cond;
    func_t _func;
};
class ThreadData
{
public:
    ThreadData(const string &name, func_t func, pthread_mutex_t *mutex, pthread_cond_t *cond)
        : _name(name), _func(func), _mutex(mutex), _cond(cond)
    {
    }

public:
    string _name;
    func_t _func;
    pthread_mutex_t *_mutex;
    pthread_cond_t *_cond;
};

void func1(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_signal(cond);
        cout << "running -- 播放" << endl;
        pthread_mutex_unlock(mutex);
    }
}
void func2(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_signal(cond);
        if (!quit)
        {
            cout << "running -- 下载" << endl;
        }
        pthread_mutex_unlock(mutex);
    }
}
void func1(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond, mutex);
        cout << name << " running -- 播放" << endl;
        pthread_mutex_unlock(mutex);
    }
}
void func2(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond, mutex);
        if (!quit)
        {
            cout << name << " running -- 下载" << endl;
        }
        pthread_mutex_unlock(mutex);
    }
}
void func3(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_signal(cond);
        cout << "running -- 刷新" << endl;
        pthread_mutex_unlock(mutex);
    }
}
void func3(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond, mutex);
        cout << name << " running -- 刷新" << endl;
        pthread_mutex_unlock(mutex);
    }
}
void func4(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_signal(cond);
        cout << "running -- 扫描用户信息" << endl;
        pthread_mutex_unlock(mutex);
    }
}
void func4(const string &name, pthread_mutex_t *mutex, pthread_cond_t *cond)
{
    while (!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond, mutex);
        cout << name << " running --扫描用户信息" << endl;
        pthread_mutex_unlock(mutex);
    }
}
void *Entry(void *args)
{
    ThreadData *td = (ThreadData *)args;
    td->_func(td->_name, td->_mutex, td->_cond);
    delete td;
    return nullptr;
}
void *Entry(void *args)
{
    ThreadData *td = (ThreadData *)args;
    td->_func(td->_name, td->_mutex, td->_cond);
    delete td;
    return nullptr;
}
// void* Entry(void* args)
// {
//     ThreadData* td=(ThreadData*)args;
//     //函数调用的时候要传的参数
//     td->_func(td->_name,td->_mutex,td->_cond);
//     delete td;
//     return nullptr;
// }
// void* Entry(void* args)
// {
//     ThreadData* td=(ThreadData*)args;
//     td->_func(td->_name,td->_mutex,td->_cond);
//     delete td;
//     return nullptr;
// }
// void* Entry(void* args)
// {
//     ThreadData* td=(ThreadData*)args;
//     td->_func(td->_name,td->_mutex,td->_cond);
//     delete td;
//     return nullptr;
// }
// void* Entry(void* args)
// {
//     ThreadData* td=(ThreadData*)args;
//     //只要传一个对象进来就可以去调用函数了
//     td->_func(td->_name,td->_mutex,td->_cond);
//     delete td;
//     return nullptr;
// }

// int main()
// {
//     pthread_mutex_t mutex;
//     pthread_cond_t cond;

//     pthread_mutex_init(&mutex,nullptr);
//     pthread_cond_init(&cond,nullptr);

//     pthread_t tid[TNUM];
//     func_t funcs[TNUM]={func1,func2,func3,func4};
//     for(int i=0;i<TNUM;i++)
//     {
//         string name="thread";
//         name+=to_string(i+1);
//         ThreadData* td=new ThreadData(name,funcs[i],&mutex,&cond);
//         pthread_create(tid+i,nullptr,Entry,(void*)td);
//     }
//     sleep(5);

//     int cnt=5;
//     while(cnt)
//     {
//         cout<<"thread resume ..."<<cnt--<<endl;
//         pthread_cond_signal(&cond);
//         sleep(1);
//     }
//     cout<<"crl done"<<endl;
//     quit=false;
//     pthread_cond_broadcast(&cond);
//     for(int i=0;i<TNUM;i++)
//     {
//         pthread_join(tid[i],nullptr);
//         cout<<"thread return:"<<tid[i]<<endl;
//     }
//     pthread_mutex_destroy(&mutex);
//     pthread_cond_destroy(&cond);
//     return 0;
// }
int main()
{
    return 0;
}
int main()
{
    pthread_mutex_t mutex;
    pthred_cond_t cond;

    pthread_mutex_init(mutex, nullptr);
    pthread_cond_init(cond, nullptr);
    pthread_t tid[TNUM];
    func_t func[TNUM] = {func1, func2, func3, func4};

    for (int i = 0; i < TNUM; i++)
    {
        string name = "thread";
        name += to_string(i + 1);
        ThreadData *td = new ThreadData(name, func[i], &mutex, &cond);
        pthread_create(tid + i, nullptr, Entry, (void *)td);
    }
    sleep(5);
    // 线程创建完成需要信号量进行通知
    int cnt = 5;
    while (cnt)
    {
        pthread_cond_signal(&cond);
        cout << "resume code..." << cnt-- << endl;
        sleep(1);
    }
    cout << "ctrl done" << endl;
    quit = true;
    for (int i = 0; i < TNUM; i++)
    {
        pthread_join(tid[i], nullptr);
        cout << "thread " << tid[i] << endl;
    }
    pthread_mutex_destroy(mutex);
    pthread_cond_destroy(cond);
    return 0;
}
int main()
{
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    // 这里初始化是要设置相关属性的
    pthread_mutex_init(&mutex, nullptr);
    pthread_cond_init(&cond, nullptr);

    pthread_t tid[TNUM];
    func_t funcs[TNUM] = {func1, func2, func3, func4};
    // 这里把线程创建好
    for (int i = 0; i < TNUM; i++)
    {
        string name = "Thread";
        name += to_string(i + 1);
        ThreadData *td = new ThreadData(name, funcs[i], &mutex, &cond);
        pthread_create(tid + i, nullptr, Entry, (void *)td);
    }
    sleep(5);

    int cnt = 5;
    while (cnt)
    {
        cout << "resume thread run code..." << cnt-- << endl;
        // 这里一次性通知一个线程来运行
        pthread_cond_signal(&cond);
        sleep(1);
    }
    cout << "ctrl done" << endl;
    quit = false;
    pthread_cond_broadcast(&cond);

    for (int i = 0; i < TNUM; i++)
    {
        pthread_join(tid[i], nullptr);
        cout << " Thread " << tid[i] << endl;
    }

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}